package com.aisile.wemedia.service.impl;

import com.aisile.common.exception.CustomExceptionCatch;
import com.aisile.model.admin.dtos.NewsAuthDto;
import com.aisile.model.admin.vos.WmNewsVo;
import com.aisile.model.common.dtos.PageResponseResult;
import com.aisile.model.common.dtos.ResponseResult;
import com.aisile.model.common.enums.AdminHttpCodeEnum;
import com.aisile.model.common.enums.AppHttpCodeEnum;
import com.aisile.model.common.enums.WemediaHttpCodeEnum;
import com.aisile.model.media.dtos.WmNewsDto;
import com.aisile.model.media.dtos.WmNewsPageReqDto;
import com.aisile.model.media.pojos.WmMaterial;
import com.aisile.model.media.pojos.WmNews;
import com.aisile.model.media.pojos.WmNewsMaterial;
import com.aisile.model.media.pojos.WmUser;
import com.aisile.utils.threadlocal.WmThreadLocalUtils;
import com.aisile.wemedia.mapper.WmMaterialMapper;
import com.aisile.wemedia.mapper.WmNewsMapper;
import com.aisile.wemedia.mapper.WmNewsMaterialMapper;
import com.aisile.wemedia.mapper.WmUserMapper;
import com.aisile.wemedia.service.WmNewsService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import groovy.lang.DelegatesTo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther:yry
 * @Date:2024/1/6 0006
 * @VERSON:1.0
 */
@Service
@SuppressWarnings("ALL")
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {


    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;
    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmUserMapper wmUserMapper;


    @Override
    public ResponseResult findAll(WmNewsPageReqDto dto) {
        // 因为是不同用户的不同文章，所以需要进入方法获取登录用户id
        WmUser wmUser = WmThreadLocalUtils.getUser();
        if (wmUser == null || wmUser.getId() == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.NEED_LOGIN);
        }
        if (dto == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.DATA_NOT_EXIST);
        }
        // 初始化分页
        dto.checkParam();
        // 封装各种查询条件
        LambdaQueryWrapper<WmNews> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 固定条件 必须要根据用户id 查询自媒体文章
        lambdaQueryWrapper.eq(WmNews::getUserId, wmUser.getId());
        // 关键字查询
        lambdaQueryWrapper.like(StringUtils.isNotBlank(dto.getKeyword()), WmNews::getTitle, dto.getKeyword());
        // 频道查询
        lambdaQueryWrapper.eq(dto.getChannelId() != null, WmNews::getChannelId, dto.getChannelId());
        // 状态查询
        lambdaQueryWrapper.eq(dto.getStatus() != null, WmNews::getStatus, dto.getStatus());
        // 时间区间  两种  between  必须传递两个参数       >=   <= 可以传递一个参数（更灵活）
        lambdaQueryWrapper.ge(dto.getBeginPubDate() != null, WmNews::getCreatedTime, dto.getBeginPubDate());
        lambdaQueryWrapper.le(dto.getEndPubDate() != null, WmNews::getCreatedTime, dto.getEndPubDate());
        // 根据时间顺序 倒序展示
        lambdaQueryWrapper.orderByDesc(WmNews::getCreatedTime);

        // 分页查询
        IPage<WmNews> ipage = this.page(new Page<>(dto.getPage(), dto.getSize()), lambdaQueryWrapper);
//        Integer.valueOf(ipage.getTotal()+"");
//        ((Long)ipage.getTotal()).intValue();
        ResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), ((Long) ipage.getTotal()).intValue());
        responseResult.setData(ipage.getRecords());
        return responseResult;
    }

    @Override
    public ResponseResult saveNews(WmNewsDto dto, Short status) {
        // 判断
        if (dto == null || status == null || status > 1 || status < 0) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.DATA_NOT_EXIST);
        }
        // 双重校验
        if (dto.getTitle() == null || dto.getContent() == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.DATA_NOT_EXIST);
        }
        // ...
        // 先保存或修改 wmnews表
        WmNews wmNews = new WmNews();
        // 深克隆   浅克隆
        //wmNews = JSON.parseObject(JSON.toJSONString(dto), WmNews.class);
        BeanUtils.copyProperties(dto, wmNews);
        if (dto.getType().equals((short) -1)) {
            wmNews.setType(null);
        }
        // 保存数据库
        this.saveWmNews(wmNews, status);

        // 在维护关系
        // 根据图片获取id
        // 内容关系
        // 文章id news_id
        // 没有素材id  但是有素材地址  需要查询
        // type = 0
        String content = dto.getContent();
        List<Map> contents = JSON.parseArray(content, Map.class);
        List<String> contentImageList = this.getImageForContents(contents);
        // 内容引用
        if (status.equals((short) 1) && contentImageList.size() > 0) {
            // 引用
            this.saveContentYinyong(contentImageList, wmNews);
        }
        // 封面关系
        // type images 弄完
        if (status.equals((short) 1)) {
            this.saveFengMianYinyong(dto, wmNews, contentImageList);
        }

        // 发送rabbitMQ  使用routingKey模式发送  生产者只关注交换机（sendAndContevnt（“交换机名称”,"key",id））


        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult findWmNewsById(Integer id) {
        if (id == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.DATA_NOT_EXIST);
        }
        WmNews wmNews = this.getById(id);
        if (wmNews == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.DATA_NOT_EXIST);
        }
        // 后台处理  前台处理
        return ResponseResult.okResult(wmNews);
    }

    @Override
    @Transactional //本地事务
    public ResponseResult delById(Integer id) {
        // 根据登录用户 进行删除
        WmUser wmUser = WmThreadLocalUtils.getUser();
        if (wmUser == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.NEED_LOGIN);
        }
        if (id == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.DATA_NOT_EXIST);
        }
        WmNews wmNews = this.getById(id);
        if (wmNews == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.DATA_NOT_EXIST);
        }
        // 要查询数据状态  然后根据状态进行判断
        if (wmNews.getStatus().equals((short) 9) && wmNews.getEnable().equals((short) 1)) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        // 删除
        this.remove(
                Wrappers.<WmNews>lambdaQuery().eq(
                        WmNews::getUserId, wmUser.getId()
                ).eq(
                        WmNews::getId, id
                )
        );
        // 删除素材关系
        wmNewsMaterialMapper.delete(
                Wrappers.<WmNewsMaterial>lambdaQuery().eq(
                        WmNewsMaterial::getNewsId, id
                )
        );
        return ResponseResult.okResult(WemediaHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult downOrUp(Integer id, Short enable) {
        // 根据登录用户 进行删除
        WmUser wmUser = WmThreadLocalUtils.getUser();
        if (wmUser == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.NEED_LOGIN);
        }
        if (id == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.DATA_NOT_EXIST);
        }
        // enable 取值范围
        if (enable < (short) 0 || enable > (short) 1) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        WmNews wmNews = this.getById(id);
        if (wmNews == null || wmNews.getStatus() != 9) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        // 审核状态满足
        wmNews.setEnable(enable);
        this.updateById(wmNews);
        // rabbitMQ 发送消息  {id:1,enable:0/1}   0  1

        // 消费者-->文章微服务--> config -->isDown(true/false) -->搜索微服务（增量索引更新）


        return ResponseResult.okResult(WemediaHttpCodeEnum.SUCCESS);
    }

    @Override
    public List<Integer> findRelease() {
        List<WmNews> list = this.list(
                Wrappers.<WmNews>lambdaQuery().eq(
                        WmNews::getStatus, (short) 8
                ).le(
                        WmNews::getPublishTime, new Date()
                )
        );
        List<Integer> ids = list.stream().map(WmNews::getId).collect(Collectors.toList());
        return ids;
    }

    @Override
    public ResponseResult findList(NewsAuthDto dto) {
        if (dto == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.DATA_NOT_EXIST);
        }
        // 分页初始化
        dto.checkParam();
        // 处理分页 page
        int page = dto.getPage();
        dto.setPage((dto.getPage() - 1) * dto.getSize());
        if (dto.getTitle() != null && !"".equals(dto.getTitle().trim())) {
            dto.setTitle("%" + dto.getTitle() + "%");
        }
        // 执行查询
        List<WmNewsVo> list = this.baseMapper.findListByPage(dto);
        int total = this.baseMapper.findCountByPage(dto);
        ResponseResult responseResult = new PageResponseResult(page,dto.getSize(),total);
        responseResult.setData(list);
        return responseResult;
    }

    @Override
    public ResponseResult findWmNewsVo(Integer id) {
        if (id == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.DATA_NOT_EXIST);
        }
        WmNews wmNews = this.getById(id);
        WmNewsVo wmNewsVo = new WmNewsVo();
        BeanUtils.copyProperties(wmNews,wmNewsVo);
        // 查询作者
        if(wmNews!=null && wmNews.getUserId()!=null){
            WmUser wmUser =  wmUserMapper.selectById(wmNews.getUserId());
            wmNewsVo.setAuthorName(wmUser.getName());
        }
        return ResponseResult.okResult(wmNewsVo);
    }

    /**
     * 内容引用
     *
     * @param iamgesList
     * @param wmNews
     */
    private void saveContentYinyong(List<String> iamgesList, WmNews wmNews) {
        this.saveYinYongGuanxi(iamgesList, wmNews, 0);
    }

    /**
     * 封面引用
     *
     * @param dto              前端传递对象(images  type= -1)
     * @param wmNews           type = null
     * @param contentImageList
     */
    private void saveFengMianYinyong(WmNewsDto dto, WmNews wmNews, List<String> contentImageList) {
        // 提取图片
        List<String> imagesList = new ArrayList<>();
        // 看看是不是自动！！！！
        if (dto.getType() == -1) {
            // 自动获取图片
            if (contentImageList != null && contentImageList.size() >= 3) {
                wmNews.setType((short) 3);
                imagesList = contentImageList.stream().limit(3).collect(Collectors.toList());
            } else if (contentImageList != null && contentImageList.size() >= 1) {
                wmNews.setType((short) 1);
                imagesList = contentImageList.stream().limit(1).collect(Collectors.toList());
            } else {
                wmNews.setType((short) 0);
            }
        } else {
            imagesList = dto.getImages();
        }
        if (imagesList != null && imagesList.size() > 0) {
            String imageUrl = "";
            for (String image : imagesList) {
                imageUrl += image + ",";
            }
            if (wmNews.getImages() == null || "".equals(wmNews.getImages())) {
                wmNews.setImages(imageUrl.substring(0, imageUrl.length() - 1));
            }
            // 保存关系
            this.saveYinYongGuanxi(imagesList, wmNews, 1);
        }
        this.updateById(wmNews);
    }


    /**
     * @param iamgesList 素材地址集合
     * @param wmNews     文章对象
     * @param type       引用类型 0 内容  1 封面
     */
    private void saveYinYongGuanxi(List<String> iamgesList, WmNews wmNews, Integer type) {
        // 查询素材id
        LambdaQueryWrapper<WmMaterial> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(WmMaterial::getUrl, iamgesList);
        lambdaQueryWrapper.eq(WmMaterial::getUserId, wmNews.getUserId());
        List<WmMaterial> list = wmMaterialMapper.selectList(lambdaQueryWrapper);
        List<Integer> materialIds = new ArrayList<>();
        list.stream().forEach(x -> {
            materialIds.add(x.getId());
        });
//        Map<String,Integer> map =  list.stream().collect(Collectors.toMap(WmMaterial::getUrl,WmMaterial::getId));
//        for(String url:iamgesList){
//            materialIds.add(map.get(url));
//        }
        // 帮你取值
        //materialIds = list.stream().map(x-> x.getId()).collect(Collectors.toList());

        // 保存  批量XML
        wmNewsMaterialMapper.saveGuanxiForMaterialIds(materialIds, wmNews.getId(), type);
    }

    /**
     * 获取内容中的图片方法
     *
     * @param contents
     * @return
     */
    private List<String> getImageForContents(List<Map> contents) {
        List<String> contentImageList = new ArrayList<>();
        contents.stream().forEach(x -> {
            if (x.get("type").equals("image")) {
                contentImageList.add((String) x.get("value"));
            }
        });
        return contentImageList;
    }


    /**
     * 保存或修改wmnews对象
     *
     * @param wmNews
     * @param status 0 草稿  1 提交
     */
    private void saveWmNews(WmNews wmNews, Short status) {
        // 获取用户id
        WmUser wmUser = WmThreadLocalUtils.getUser();
        if (wmUser == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.NEED_LOGIN);
        }
        if (wmNews == null) {
            CustomExceptionCatch.catchWemedia(WemediaHttpCodeEnum.DATA_NOT_EXIST);
        }
        wmNews.setStatus(status);
        if (wmNews.getId() == null) {
            // 添加
            wmNews.setUserId(wmUser.getId());
            wmNews.setCreatedTime(new Date());
            // 提交时间（只有提交了才有）
            if (status.equals((short) 1)) {
                wmNews.setSubmitedTime(new Date());
            }
            wmNews.setEnable((short) 0);
            this.save(wmNews);
        } else {
            // 修改
            this.updateById(wmNews);
            // 删除 关系
            wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(
                    WmNewsMaterial::getNewsId, wmNews.getId()
            ));
        }
    }

}
